home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
assemblr
/
library
/
lowlevel
/
fdisk
/
mfdisk.asm
< prev
next >
Wrap
Assembly Source File
|
1989-08-24
|
18KB
|
450 lines
page ,132
title MFDISK - FDISK clone & multiple boot-record modifier
;------------------------------------------------------------------------------
; This program will write a new boot sector to the first HD drive
; that prompts for the partition you want to boot from (1-4).
; To the question 'Boot partition (1-4):' you have to answer with
; the number of the partition you want to boot from (1-4).
;
; The program must be compiled as a .COM file (remember exe2bin)
; and run under MesSDOS.
;
; The makefile for compiling under MesSDOS should look like:
;
; mfdisk.obj: mfdisk.asm
; masm mfdisk;
;
; mfdisk.com: mfdisk.obj
; link mfdisk;
; exe2bin mfdisk.exe mfdisk.com
; del mfdisk.exe
;
; When the program is run, it produces a message telling you what
; it is going to do. At this time you can abort it by typing
; <CTRL-C> or type <CR> to allow it to modify the hard-disk.
;
; Now you can boot multiple operating systems (MesSDOS, OS/2,
; SCO Xenix and Minix) from the same hard-disk). To do so you
; had to partition your hard-disk to separate partitions, each
; with another operating-system boot.
;
; Motti (Mordehai) Bazar
;
; uucp : ..uunet!ocsmd!motti
; bitnet : motti%ocsmd@uunet.uu.net
; internet: motti@ocsmd.uu.net
;
; snail: Online Computer Systems, Inc.
; 20251 Century Blvd.
; Germantown, MD 20874
;
; vox: (301) 428-3700
;
; This utility is distributed for personal use only. Use it, modify it
; or do anything you like, just live this comment and let me know of
; any bugs or enhancements you made to it, thanks.
;
;------------------------------------------------------------------------------
;-------------------------
; First, some definitions
;-------------------------
VIDEO equ 10h
KBD equ 16h
DISKIO equ 13h
DOS equ 21h
CR equ 0Dh
LF equ 0Ah
;---------------------------
; Here comes the real thing
;---------------------------
CODE segment byte public 'CODE'
assume cs:CODE, ds:CODE
org 100h
WRITBOOT:
jmp START ; jump around
DISKBUF db 512 dup(?)
HELLOMS db CR, LF
db 'MFDISK - Multiple boot FDISK clone', CR, LF
db CR, LF
db 'This program will read the boot sector from the first disk', CR, LF
db 'and merge the partition table from it with the boot program', CR, LF
db 'supplied and write it all back to the disk overlaying what', CR, LF
db 'was there. The resultant boot program will prompt for the', CR, LF
db 'desired partition for booting (1-4).', CR, LF
db CR, LF
db 'The original boot program will be saved in a file named', CR, LF
db 'IBMBOOT.SVE in the default directory.', CR, LF
db CR, LF
db '<CR> = continue, CONTROL-C = abort ... $'
CRLF db CR, LF, '$'
IBMBOOT db 'IBMBOOT.SVE',0
OKMSG db CR, LF, 'Boot sector updated', CR, LF, '$'
ERMSG1 db CR, LF, 'Error reading boot sector', CR, LF, '$'
ERMSG2 db CR, LF, 'Cannot open save file', CR, LF, '$'
ERMSG3 db CR, LF, 'Cannot write save file', CR, LF, '$'
ERMSG4 db CR, LF, 'Cannot close save file', CR, LF, '$'
ERMSG5 db CR, LF, 'Cannot write boot sector', CR, LF, '$'
BOOTHDL dw 0 ; Boot backup file handle
START:
;----------------------
; Show opening message
;----------------------
mov dx, offset HELLOMS
mov ah, 9
int DOS
RDCNS:
;---------------------------------------------------------
; Get user's response: <CR> or CONTROL-C (aborted by DOS)
;---------------------------------------------------------
mov ah, 0Ch
mov al, 1
int DOS
cmp al, CR ; <CR> key ?
jne RDCNS ; No, retry
;-----------------------------------------
; <CR> typed, go and modify the hard-disk
;-----------------------------------------
mov dx, offset CRLF ; Echo <CR><LF>
mov ah, 9
int DOS
;------------------------------------
; Read the sector from the hard-disk
;------------------------------------
mov si, 5 ; Retry for 5 times
RDDSK:
push si ; Save retry counter
mov ah, 2 ; Read disk
mov al, 1 ; 1 sector
mov bx, offset DISKBUF ; Point to buffer
mov ch, 0 ; Cylinder 0
mov cl, 1 ; Sector 1
mov dh, 0 ; Track 0
mov dl, 80h ; Harddisk 0
int DISKIO
pop si
jnc RDOK ; Good read
dec si ; More tries?
jnz RDDSK ; Yes, try again
mov dx, offset ERMSG1 ; No, point to trouble message
mov ah, 9 ; say console write
int DOS ; can't read boot sector
mov ah, 4Ch ; say terminate
mov al, 1 ; error return code
int DOS
;---------------------------------
; Create the file to save it into
;---------------------------------
RDOK:
mov dx, offset IBMBOOT ; get file name
mov ah, 3Ch ; say create it
sub cx, cx ; zero attribute
int DOS
jnc OPENOK ; file opened
mov dx, offset ERMSG2 ; can't open save file
mov ah, 9
int DOS ; tell 'em
mov ah, 4Ch ; say terminate
mov al, 2 ; reason
int DOS
;---------------------------------
; Write sector to the backup file
;---------------------------------
OPENOK:
mov BOOTHDL, ax ; save handle
mov bx, ax ; and put in bx
mov ah, 40h ; say write to file
mov dx, offset DISKBUF ; get location
mov cx, 512 ; say 1 sector
int DOS ; ask to have it done
jnc WRTOK ; good write
mov dx, offset ERMSG3 ; can't write to save file
mov ah, 9
int DOS ; tell 'em
mov ah, 4Ch ; say terminate
mov al, 3 ; reason
int DOS
;-------------------
; Close backup file
;-------------------
WRTOK:
mov ah, 3Eh ; say close file
mov bx, BOOTHDL
int DOS
jnc CLOSOK ; closed ok
mov dx, offset ERMSG4 ; can't close save file
mov ah, 9
int DOS ; tell 'em
mov ah, 4Ch ; say terminate
mov al, 4 ; reason
int DOS
;-----------------------------------------------------
; Copy the read partition table into our sector so it
; will use it when booting.
;-----------------------------------------------------
CLOSOK:
push si
mov si, offset DISKBUF+1BEh ; start of partition table
mov di, offset BOOTSEC+1BEh ; ditto for new sector
cld ; make direction positive
mov cx, 4*16+2 ; how many bytes to move
rep movsb ; move em
;----------------------------------------
; Write our sector back to the hard-disk
;----------------------------------------
mov si, 5 ; 5 retries
WRTBOOT:
push si
mov ah, 3 ; say write to disk
mov al, 1 ; say 1 sector
mov bx, offset BOOTSEC ; point to sector to write
mov cx, 1 ; say sector 1
mov dx, 80h
int DISKIO ; do the io
pop si
jnc UPDOK ; good write to boot sector
dec si ; count retries
jnz WRTBOOT ; try again
mov dx, offset ERMSG5 ; can't write boot sector file
mov ah, 9
int DOS ; tell 'em
mov ah, 4Ch ; say terminate
mov al, 5 ; reason
int DOS
;----------------------------------------------------------
; Inform the user that the operation finished successfully
; and exit back to DOS.
;----------------------------------------------------------
UPDOK:
mov dx, offset OKMSG ; say we did it
mov ah, 9
int DOS ; tell 'em
mov ah, 4Ch ; say terminate
mov al, 0 ; good return code
int DOS
;****************************************************************
;* BOOTSEC *
;* *
;* Here comes the sector patched into the hard-disk *
;****************************************************************
BOOTSEC:
BSTART equ $ ; Start offset of our boot sector
BOOTLOC equ 7C00h ; Boot sector loaded there
BOOTSIG equ 7DFEh ; Boot sector signal address
MOVETO equ 600h ; Where to move it
PARTTBL equ BSTART + 1BEh ; Start of partition table in our code
cli
xor ax, ax ; (AX) = 0
mov ss, ax ; (SS) = Set stack segment to 0
mov sp, offset BOOTLOC ; Get boot code address
mov si, sp ; (SI) = Source address
mov es, ax ; (ES) = 0
mov ds, ax ; (DS) = 0
sti
cld
mov di, MOVETO ; (DI) = Destination address
mov cx, 100h ; (CX) = # of words to move
rep movsw ; Move it
;------------------------------------
; Setup to continue the boot process
;------------------------------------
mov ax, MOVETO + offset RELBOOT - BSTART
push ax
ret
RELBOOT:
;----------------------------------
; Set all partitions as not active
;----------------------------------
mov bx, MOVETO + 1BEh
mov byte ptr [bx], 0
mov byte ptr 16[bx], 0
mov byte ptr 32[bx], 0
mov byte ptr 48[bx], 0
;------------------------------------------
; Show boot prompt 'Boot partition (1-4):'
;------------------------------------------
WRPRMPT:
mov si, MOVETO + offset BOOTMSG - BSTART
lodsb
mov cl, al
xor ch, ch
WR000:
lodsb
mov bx, 7
mov ah, 0Eh
int VIDEO
loop WR000
;-------------------------------
; Get user's response & show it
;-------------------------------
mov ah, 0 ; Get keyboard input
int KBD
push ax
mov ah, 10 ; Show it
mov cx, 1
int VIDEO
pop ax
;----------------------------------
; Check for legal partition number
;----------------------------------
cmp al, '1' ; # below 1 ?
jb WRPRMPT ; Yes, error
cmp al, '4' ; # above 4 ?
ja WRPRMPT ; Yes, error
;--------------------------------------
; AL contains partition # to boot from
;--------------------------------------
and al, 7 ; Mask partition #
;----------------------------------------
; Calculate partition table entry to use
;----------------------------------------
mov si, MOVETO + 1BEh ; point to first entry
CALCPART:
dec al
jz GOTPART
add si, 16 ; Advance to next partition
jmp short CALCPART
GOTPART:
;-----------------------------------------------------
; Set the requested partition as the active partition
;-----------------------------------------------------
mov byte ptr[si], 80h
push si
push bx
mov ax, 0301h
mov bx, MOVETO
mov cx, 1
mov dx, 80h
int diskio
pop bx
pop si
;-------------------------------------------------------------
; Now go and try to read the selected partition's boot sector
;-------------------------------------------------------------
mov dx, [si] ; (DH) = drive, (DL) = head
mov cx, [si+2] ; (CH) = track, (CL) = sector
mov bp, si ; Save partition pointer
mov di, 5 ; Set retry count
RDBOOT:
mov bx, BOOTLOC ; Location for boot
mov ax, 0201h ; Read 1 sector
push di
int DISKIO ; Go read
pop di
jnc GOODRD ; Good read
xor ax, ax ; Recalibrate
int DISKIO
dec di ; Decrement retries count
jnz RDBOOT ; Counter at zero ?
;---------------------------------------------------
; Can't read boot sector, show a message and hangup
;---------------------------------------------------
mov si, MOVETO + offset MSG2 - BSTART
WRMSG:
lodsb ; Get message length
mov cl, al
xor ch, ch
WR002:
lodsb
mov bx, 7
mov ah, 0Eh
int VIDEO
loop WR002
jmp WRPRMPT
;------------------------------------------------
; Boot sector read, check for the boot signature
;------------------------------------------------
GOODRD:
mov si, MOVETO + offset MSG3 - BSTART ; Point to no boot msg
mov bx, BOOTSIG
cmp word ptr [bx], 0AA55h ; Check for the boot signature
jne WRMSG
;-----------------------------------------------------------------
; Finaly, go and boot.
;
; Before booting set:
; SI - points to partition table entry we are booting from
; BX - starting cylinder number of this partition
;-----------------------------------------------------------------
mov si, bp ; Restore partition table pointer
mov ax, word ptr 2[si] ; AH-cyl, AL-sec
xor bh, bh
mov bl, al
shl bx, 1
shl bx, 1 ; BH-2 msb bits
mov bl, ah ; BL-8 lsb bits
mov ax, offset BOOTLOC ; Where partition boot start
push ax
ret
BOOTMSG db LMSGB, CR, LF, 'Boot partition (1-4): '
LMSGB equ ($-BOOTMSG)-1
MSG2 db LMSG2, CR, LF, 'Error loading operating system'
LMSG2 equ ($-MSG2)-1
MSG3 db LMSG3, CR, LF, 'Missing operating system'
LMSG3 equ ($-MSG3)-1
org BSTART + 512
CODE ends
end WRITBOOT